#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"

#define STACK_SIZE     2048
#define SEMP_MAX_COUNT 5

osSemaphoreId_t g_emptySem;
osSemaphoreId_t g_fullSem;
int g_ProductNum = 0;

/* 生产者任务 */
void TaskProducer(void *arg) {

    while (1) {
        osSemaphoreAcquire(g_emptySem, osWaitForever);
 g_ProductNum++;
        printf("[%s] Add a product, now: %d.\r\n", 
  osThreadGetName(osThreadGetId()), g_ProductNum);

        osSemaphoreRelease( g_fullSem );
        osDelay( 10 );
    }
}

void TaskConsumer(void *arg) {

    while (1) {
        osSemaphoreAcquire(g_fullSem, osWaitForever);
        g_ProductNum--;

        printf("[%s] Delete a product, now: %d.\r\n", 
  osThreadGetName(osThreadGetId()), g_ProductNum);

        osSemaphoreRelease( g_emptySem );
        osDelay( 10 );
    }
}

/* 任务创建函数 */
osThreadId_t TaskNew(char *name, osThreadFunc_t func, int *arg) {
    osThreadAttr_t attr = {
        name, 0, NULL, 0, NULL, 1024*2, osPriorityNormal, 0, 0
    };

    osThreadId_t tid = osThreadNew(func, arg, &attr);
    if (tid == NULL) {
        printf("[Main] %s Create Failed\r\n", name);
    } else {
        printf("[Main] %s Create OK\r\n", name);
    }

    return tid;
}
void SempDemoMain(int *arg) {
    (int)arg;

    g_emptySem  = osSemaphoreNew(SEMP_MAX_COUNT, SEMP_MAX_COUNT, NULL);
    g_fullSem   = osSemaphoreNew(SEMP_MAX_COUNT, 0, NULL);
 
    osThreadId_t ptid1 = TaskNew("producer1", TaskProducer, NULL);
    osThreadId_t ptid2 = TaskNew("producer2", TaskProducer, NULL);
    osThreadId_t ctid1 = TaskNew("consumer1", TaskConsumer, NULL);
    osThreadId_t ctid2 = TaskNew("consumer2", TaskConsumer, NULL);
    osThreadId_t ctid3 = TaskNew("consumer3", TaskConsumer, NULL);

    osDelay( 200 );

    osThreadTerminate( ptid1 );
    osThreadTerminate( ptid2 );
    osThreadTerminate( ctid1 );
    osThreadTerminate( ctid2 );
    osThreadTerminate( ctid3 );

    osSemaphoreDelete( g_emptySem );
    osSemaphoreDelete( g_fullSem );

    printf("[Main] Exit \r\n" );
}

SYS_RUN( SempDemoMain );

